package fun.huixi.weiju.business.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import fun.huixi.weiju.base.BaseEntity;
import fun.huixi.weiju.business.DynamicBusiness;
import fun.huixi.weiju.exception.BusinessException;
import fun.huixi.weiju.page.PageData;
import fun.huixi.weiju.pojo.dto.dynamic.PageQueryDynamicCommentDTO;
import fun.huixi.weiju.pojo.dto.dynamic.QueryDynamicDTO;
import fun.huixi.weiju.pojo.dto.dynamic.SaveDynamicCommentDTO;
import fun.huixi.weiju.pojo.dto.dynamic.SaveDynamicDTO;
import fun.huixi.weiju.pojo.entity.WjDynamic;
import fun.huixi.weiju.pojo.entity.WjDynamicComment;
import fun.huixi.weiju.pojo.entity.WjDynamicEndorse;
import fun.huixi.weiju.pojo.entity.WjUser;
import fun.huixi.weiju.pojo.vo.dynamic.DynamicCommentItemVO;
import fun.huixi.weiju.pojo.vo.dynamic.DynamicListVO;
import fun.huixi.weiju.service.WjDynamicCommentService;
import fun.huixi.weiju.service.WjDynamicEndorseService;
import fun.huixi.weiju.service.WjDynamicService;
import fun.huixi.weiju.service.WjUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 动态业务实现类
 *
 * @param
 * @Author Zol
 * @Date 2021/11/10
 * @return
 **/
@Service
public class DynamicBusinessImpl implements DynamicBusiness {

    @Resource
    private WjDynamicService dynamicService;
    @Resource
    private WjUserService userService;
    @Resource
    private WjDynamicEndorseService dynamicEndorseService;
    @Resource
    private WjDynamicCommentService dynamicCommentService;

    @Override
    public PageData<DynamicListVO> listPageDynamic(Integer userId, QueryDynamicDTO param) {
        PageData<DynamicListVO> pageData = new PageData<>();
        // 分页查询
        Integer current = param.getCurrent();
        Integer size = param.getSize();
        // TODO：isHome 是否是主页，待考虑
        Page<WjDynamic> page = dynamicService.lambdaQuery()
                .eq(WjDynamic::getTagDictId, param.getTagDictId())
                .orderByDesc(WjDynamic::getCreateTime)
                .page(new Page<>(current, size));
        BeanUtil.copyProperties(page, pageData);
        if (0 == page.getTotal()) {
            return pageData;
        }
        // 获取用户信息<用户ID，用户信息>
        Set<Integer> userSet = page.getRecords().stream().map(WjDynamic::getUserId).collect(Collectors.toSet());
        Map<Integer, WjUser> userMap = userService.queryUserInfoByUserIds(userSet);

        // 查询当前用户-是否点赞
        List<Integer> dynamicIdList = page.getRecords().stream().map(WjDynamic::getDynamicId).collect(Collectors.toList());
        // <用户ID,是否点赞>
        Map<Integer, Boolean> userEndorseMap = dynamicEndorseService.queryUserOrEndorseByUserId(userId, dynamicIdList);
        // 组装返回值
        ArrayList<DynamicListVO> dynamicList = new ArrayList<>();
        page.getRecords().stream().forEach(item -> {
            DynamicListVO vo = new DynamicListVO();
            // 自动赋值
            BeanUtil.copyProperties(item, vo);
            // 用户信息
            WjUser wjUser = userMap.get(item.getUserId());
            BeanUtil.copyProperties(wjUser, vo);
            // 是否点赞
            vo.setIsEndorse(userEndorseMap.get(item.getDynamicId()));
            // 上次在线时间 TODO

            dynamicList.add(vo);
        });
        pageData.setRecords(dynamicList);
        // 返回值
        return pageData;
    }

    /**
     * 点赞动态
     *
     * @param userId    用户id
     * @param dynamicId 动态id
     * @return void
     * @Author 叶秋
     * @Date 2021/11/24 11:21
     **/
    @Override
    public void endorseDynamic(Integer userId, Integer dynamicId) {

        // 添加动态点赞记录
        WjDynamicEndorse wjDynamicEndorse = new WjDynamicEndorse();
        wjDynamicEndorse.setDynamicId(dynamicId);
        wjDynamicEndorse.setUserId(userId);
        dynamicEndorseService.save(wjDynamicEndorse);

        // 修改动态的点赞记录
        WjDynamic dynamic = dynamicService.lambdaQuery()
                .select(WjDynamic::getDynamicId, WjDynamic::getEndorseCount, BaseEntity::getVersion)
                .eq(WjDynamic::getDynamicId, dynamicId)
                .one();

        Integer endorseCount = dynamic.getEndorseCount();
        dynamic.setEndorseCount(endorseCount + 1);

        dynamicService.updateById(dynamic);

    }

    /**
     * 取消点赞的动态
     *
     * @param userId    用户id
     * @param dynamicId 动态id
     * @return void
     * @Author 叶秋
     * @Date 2021/11/29 14:36
     **/
    @Override
    public void cancelDynamicEndorse(Integer userId, Integer dynamicId) {

        List<WjDynamicEndorse> list = dynamicEndorseService.lambdaQuery()
                .eq(WjDynamicEndorse::getUserId, userId)
                .eq(WjDynamicEndorse::getDynamicId, dynamicId)
                .list();

        List<Integer> collect = list.stream().map(WjDynamicEndorse::getDynamicEndorseId)
                .collect(Collectors.toList());

        if(collect.size() == 0){
            return;
        }

        boolean b = dynamicEndorseService.removeByIds(collect);

    }

    /**
     * 分页查询动态参数
     *
     * @param userId                     查询人用户id
     * @param pageQueryDynamicCommentDTO 查询参数
     * @return fun.huixi.weiju.page.PageData<fun.huixi.weiju.pojo.vo.dynamic.DynamicCommentItemVO>
     * @Author 叶秋
     * @Date 2021/12/10 10:28
     **/
    @Override
    public PageData<DynamicCommentItemVO> pageQueryDynamicComment(Integer userId, PageQueryDynamicCommentDTO pageQueryDynamicCommentDTO) {

        Integer current = pageQueryDynamicCommentDTO.getCurrent();
        Integer size = pageQueryDynamicCommentDTO.getSize();
        Integer dynamicId = pageQueryDynamicCommentDTO.getDynamicId();

        PageData<DynamicCommentItemVO> pageData = new PageData<>();

        // 分页查询动态评论
        Page<WjDynamicComment> page = dynamicCommentService.lambdaQuery()
                .eq(WjDynamicComment::getDynamicId, dynamicId)
                .orderByDesc(BaseEntity::getCreateTime)
                .page(new Page<>(current, size));
        BeanUtil.copyProperties(page, pageData);

        if(page.getTotal() == 0){
            return pageData;
        }

        // 评论人的用户信息
        Set<Integer> userIdSet = page.getRecords().stream().map(WjDynamicComment::getUserId)
                .collect(Collectors.toSet());
        Map<Integer, WjUser> userIdToUserInfoMap = userService.lambdaQuery()
                .select(WjUser::getUserId, WjUser::getNickName, WjUser::getHeadPortrait)
                .in(WjUser::getUserId, userIdSet)
                .list().stream().collect(Collectors.toMap(WjUser::getUserId, item -> item));

        // 查询动态评论是否点赞
        // TODO: 2021/12/10 展示不做这一部份 

        ArrayList<DynamicCommentItemVO> dynamicCommentItemVOS = new ArrayList<>();

        for (WjDynamicComment record : page.getRecords()) {

            DynamicCommentItemVO dynamicCommentItemVO = new DynamicCommentItemVO();

            // 赋值用户信息
            WjUser wjUser = userIdToUserInfoMap.get(record.getUserId());
            BeanUtil.copyProperties(wjUser, dynamicCommentItemVO);

            // 赋值动态评论信息
            BeanUtil.copyProperties(record, dynamicCommentItemVO);

            // 是否点赞

            dynamicCommentItemVOS.add(dynamicCommentItemVO);

        }

        pageData.setRecords(dynamicCommentItemVOS);
        return pageData;
    }

    /**
     * 保存动态评论
     *
     * @param saveDynamicCommentDTO 动态评论相关参数
     * @return void
     * @Author 叶秋
     * @Date 2021/11/29 14:46
     **/
    @Override
    public void saveDynamicComment(SaveDynamicCommentDTO saveDynamicCommentDTO) {

        Integer dynamicId = saveDynamicCommentDTO.getDynamicId();

        WjDynamicComment wjDynamicComment = new WjDynamicComment();
        BeanUtil.copyProperties(saveDynamicCommentDTO, wjDynamicComment);

        wjDynamicComment.setEndorseCount(0);

        boolean save = dynamicCommentService.save(wjDynamicComment);

        if(!save){
            throw new BusinessException("保存评论失败");
        }

        // 保存成功后增加动态的评论数量
        WjDynamic dynamic = dynamicService.getById(dynamicId);
        dynamic.setCommentCount(dynamic.getCommentCount() + 1);
        dynamicService.updateById(dynamic);


    }

    /**
     * 删除动态评论
     *
     * @param dynamicCommentId 动态评论id
     * @return void
     * @Author 叶秋
     * @Date 2021/11/29 15:00
     **/
    @Override
    public void removeDynamicComment(Integer dynamicCommentId) {


        WjDynamicComment dynamicComment = dynamicCommentService.getById(dynamicCommentId);
        Integer dynamicId = dynamicComment.getDynamicId();

        // 删除评论
        dynamicCommentService.removeById(dynamicCommentId);

        // 修改动态的评论数量
        // 保存成功后增加动态的评论数量
        WjDynamic dynamic = dynamicService.getById(dynamicId);
        dynamic.setCommentCount(dynamic.getCommentCount() - 1);
        dynamicService.updateById(dynamic);


    }

    /**
     * 保存动态
     *
     * @param userId         用户id
     * @param saveDynamicDTO 保存动态参数
     * @return void
     * @Author 叶秋
     * @Date 2021/11/29 15:18
     **/
    @Override
    public void saveDynamic(Integer userId, SaveDynamicDTO saveDynamicDTO) {

        WjDynamic dynamic = new WjDynamic();
        BeanUtil.copyProperties(saveDynamicDTO, dynamic);

        dynamic.setUserId(userId);
        dynamic.setEndorseCount(0);
        dynamic.setCommentCount(0);
        dynamic.setBrowseCount(0);

        boolean save = dynamicService.save(dynamic);

        if(!save){
            throw new BusinessException("保存动态失败");
        }


    }


}
